#include "key.h"

button btns[1];     //按键数据
rt_event_t key_event = RT_NULL;

/******************************************************************
 * 函 数 名 key_init
 * 函 数 说 按键结构体初始化
 * 函 数 形 参：无
 * 函 数 返 回：无
 * 备       注：无
******************************************************************/
void key_init(void)
{
    btns[0].gpiox = KEY_B0_GPIO_Port;
    btns[0].pin = KEY_B0_Pin;
    btns[0].level = 1;
    btns[0].id = 0;

}

/******************************************************************
 * 函 数 名 key_proc
 * 函 数 说 按键处理函数
 * 函 数 形 参：btns：按键结构体指针
 * 函 数 返 回：无
 * 备       注：无
******************************************************************/
void key_proc(button *btn)
{
    //获取当前按键电平
    uint32_t gpio_level = KEY_readpin(btn->gpiox, btn->pin);

    //如果按键状态大于0，则递增计数器
    if(btn->state > 0) btn->tick++;

    //如果当前电平与按键记录电平不一致，进行消抖处理
    if(btn->level != gpio_level)
    {
        //计数达到3次时，确认电平变化
        if(++(btn->debouce_cnt) >= 3)
        {
            btn->level = gpio_level;//更新电平
            btn->debouce_cnt = 0;//重置去抖计数器
        }
    }
    else{
        btn->debouce_cnt = 0;//重置去抖计数器
    }

    //按键状态机
    switch(btn->state)
    {
        case 0://初始状态
        if(!btn->level)//按键按下
        {
            btn->tick = 0; //重置计数值
            btn->repeat = 1;//初始化按键重复次数
            btn->state = 1;//进入按键按下状态
        }
        break;
        case 1://按键按下状态
        if(btn->level)//按键松开
        {
            if(btn->tick > 30)
            {/***********************按键长按逻辑******************/
                    
                switch (btn->id)
                {
                case 0: 
                    break;
                case 1:
                    break;
                default:
                    break;
                }  
                btn->repeat = 0;//防止释放再次触发单击事件
            }   
            btn->tick = 0;  //重置计数器
            btn->state = 2;//进入按键释放状态
        }
        break;
        case 2://按键释放状态
        if(btn->tick > 15)//计数达到阈值
        {
            btn->state = 0;//返回初始状态

             if(btn->repeat == 1)
             {/***********************按键短按逻辑******************/ 
                switch (btn->id)
                {
                    //控制target
                case 0:rt_kprintf("key1 click\n");
                rt_event_send(key_event, key_b0_short_flag);
                break;
                case 1:rt_kprintf("key2 click\n");
                
                break;
                case 2:rt_kprintf("key3 click\n");
                break;
                case 3:rt_kprintf("key4 click\n");
                break;
                case 4:rt_kprintf("key5 click\n");
                
                break;
                default:
                    break;
                }
             }   
             /***********************按键多击逻辑******************/ 
            if(btn->repeat == 2)
            { 

                switch (btn->id)
                {
                case 0: rt_kprintf("key1 double click\n");
                rt_event_send(key_event, key_b0_double_flag);
                    break;
                case 1:
                    break;
                default:
                    break;
                }
                
            }            
        }
        else{
            if(!btn->level)  //按键再次按下
            {
                btn->repeat++;  //递增重复计数
                btn->tick = 0;  //重置计数器
                btn->state = 1; //返回按键按下状态

            }
        }
        break;
    }
}


/******************************************************************
 * 函 数 名 key_rtread_entry
 * 函 数 说 按键线程
 * 函 数 形 参：无
 * 函 数 返 回：无
 * 备       注：无
******************************************************************/
void key_thread_entry(void *parameter)
{
    key_init();
    key_event = rt_event_create("key_event", RT_IPC_FLAG_FIFO);
    if(key_event == RT_NULL)
    {
        rt_kprintf("key_event create fall\n");
    }
    while (1)
    {
        for(uint8_t i=0; i< sizeof(btns)/sizeof(button); i++)
        {
            key_proc(&btns[i]);
        }
        rt_thread_delay(10);
    } 
}

